package com.scalar.chiptrack.operations.process.parser;

import com.scalar.ScalarException;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.db.DBXException;
import com.scalar.chiptrack.operations.process.dao.WorkflowDBManager;
import com.scalar.chiptrack.operations.process.dao.ProductDao;
import com.scalar.chiptrack.operations.process.WorkflowProcess;
import com.scalar.chiptrack.utils.Logger;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;

import java.io.File;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.util.*;

/** Product Parser for Ikanos  CLIENT. THIS IS FOR ONE TIME PORTING.
 * User: Sujan
 * Date: Jul 14, 2008
 * Time: 3:23:27 PM
 */
public class ProductParser
{
    private Logger m_parserLogger   = null;
    HashMap processParametersMap = null;

    public ProductParser() throws Exception
    {
        try
        {
            m_parserLogger = new Logger(  "./logs", "productPorting", "Parser", "debug", 1024 * 10000, 1 );
        }
        catch( Exception e )
        {
            e.printStackTrace();
        }
    }
    // To be implemented by sub classes
    public void execute() throws Exception
    {
        boolean success = false;
        printHeader();
        File productFile = getFileForPorting(System.getProperty ( "productFile" ));
        log ( "Parsing File:"  + productFile.getName() );
        System.out.println ( "Parsing Product File:"  + productFile.getName());
        log ( "Parsing Product sheet...." );
        System.out.println ( "Parsing Product sheet...." );

        ArrayList baseProductList = parseProductFile( productFile );

        log ( "Parsing Prodcut sheet completed..." );
        System.out.println ( "Parsing Product sheet completed..." );
        log ( "Parsing completed successfully..." );
        System.out.println ( "Parsing completed successfully.....");
        log ( "Porting Product info..." );
        System.out.println ( "Porting Product info..." );

        DBTransaction dbTransaction = null;
        String portingStatusMsg = null;
        try
        {
            processParametersMap = WorkflowDBManager.getAllProcessParameters();
            //dbTransaction = DBTransaction.getInstance();
            //dbTransaction.begin();
            //SalesParserDAO.saveSalesOrders( dbTransaction, lineItemList );
            for ( int i=0; i < baseProductList.size(); i++ )
            {
                BaseProduct baseProduct = (BaseProduct)baseProductList.get(i);
                ProductDao productDao  = new ProductDao();
                String productId = productDao.saveBaseProduct(baseProduct.getBaseProductName(),"");
		        if( !productId.equals( "exists" ) ) //base product not exists
                {
                    String xpdl = getXPDL( baseProduct );
                    
                    log( "Porting Base Product:" + baseProduct.getBaseProductName() );
                    ByteArrayInputStream bais = new ByteArrayInputStream(xpdl.getBytes() );
                    String flag = WorkflowProcess.saveProcessToDB( bais , baseProduct.getBaseProductName() , System.getProperty("xpdlDirectory") + "/" + baseProduct.getBaseProductName()+".xpdl" , "Database" );
                    log ( "status=" + flag );
                }
                else
                {
                    log( "**NOT PORTED** Base Product '"+baseProduct.getBaseProductName()+"' already exists");
                }
            }
            /*if ( dbTransaction != null )
            {
                dbTransaction.commit();
            }*/
            success = true;
        }
        catch ( Exception e )
        {
            log ( "Exception while porting Products:", e );
            throw e;
        }
        finally
        {
            if ( dbTransaction != null )
            {
                if ( !success )
                {
                    try { dbTransaction.rollback(); } catch ( DBXException ignore ){}
                }
                dbTransaction = null;
            }
        }
        if ( success ) //SEND PORTING STATUS MAIL
        {
            System.out.println ( "********SEE LOG FILE FOR NOT PORTED PRODUCTS********" );
            log ( "Porting Products completed successfully...." );
            System.out.println ( "Porting Products completed successfully...." );

        }
        else
        {
            log ( "Unable to port the Product information...." );
            System.out.println ( "Unable to port the Product information..." );
        }
    }
    private void printHeader()
    {
        String info = "\n\n+----------- Running Product Porting on " + new java.util.Date( System.currentTimeMillis() ) + " -------------+\n" +
                 "\n+---------------------------------------------------------------+\n" +
                 "+                                                                \n" +
                 "+            Product Porting - Beta          \n" +
                 "+                                                                \n" +
                 "+    Copy Right (C) 2008 - ScalarSoft Inc., All rights reserved.  \n" +
                 "+                                                                \n" +
                 "+---------------------------------------------------------------+\n" ;
        System.out.println( info );
        log( info );
    }
    private void log( String message )
    {
        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            m_parserLogger.logDebug( message + AdaptorConstants.LINE_SEPARATOR );
        }
        else
        {
            System.out.println( message );
        }
    }
    private void log( String message, Throwable ex )
    {
        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            m_parserLogger.logError( message + AdaptorConstants.LINE_SEPARATOR, ex );
        }
        else
        {
            System.out.println( message + ":" + ex.getMessage() );
        }
    }

   private File getFileForPorting ( String salesPortingFile ) throws ScalarException
    {
        if ( salesPortingFile == null || salesPortingFile.trim().length() == 0 )
        {
            log ( "Sales Porting File Name not specified" );
            System.out.println ( "Sales Porting File Name not specified" );
            throw new ScalarException( "Sales Porting File Name not specified" );
        }
        File portingFile = new File ( salesPortingFile );
        if ( portingFile.exists() == false && portingFile.isFile() == false )
        {
            log ( "Sales Porting File:" + salesPortingFile + " Does not exist" );
            throw new ScalarException( salesPortingFile + " does not exist" );
        }
        else
        {
            log ( "Sales Porting File:" + salesPortingFile + " Found" );
            System.out.println ( "Sales Porting File:" + salesPortingFile + " Found" );
        }
        return portingFile;
    }
    private ArrayList parseProductFile ( File productPortingFile ) throws IOException, BiffException
    {
        Workbook workbook 	        = Workbook.getWorkbook( productPortingFile );
        Sheet basePartsSheet 		= workbook.getSheet( "Base Part master table" );
        Sheet assmPartsSheet 		= workbook.getSheet( "part number assy thru ship" );
        Map baseProductMap = new HashMap();
        Cell[] cells 			    = null;
        int noOfCells               = 0;
        int noOfRows                = basePartsSheet.getRows();
        for ( int rowCount = 3; rowCount < noOfRows; rowCount++ )
        {
            cells = basePartsSheet.getRow( rowCount );
            noOfCells = cells.length;
            BaseProduct baseProduct = null;
            Activity fabActivity = null;
            Activity wsActivity = null;
            Activity sortActivity = null;
            Activity dbActivity = null;
            if ( noOfCells > 0  )
            {
                if ( cells[0].getContents() != null && cells[0].getContents().trim().length() > 0 ) //base product Name
                {
                    String baseProductName = cells[0].getContents().trim();
                    if ( baseProductMap.containsKey( baseProductName ) )
                    {
                        baseProduct = (BaseProduct)baseProductMap.get( baseProductName );
                    }
                    else
                    {
                        baseProduct = new BaseProduct();
                        baseProduct.setBaseProductName( baseProductName );
                        baseProductMap.put ( baseProductName, baseProduct );
                    }
                }
                else
                {
                    log( "**NOT PORTED**Base Product Name Missing for the row:" + (rowCount+1) );
                    continue;
                }

                if ( noOfCells > 1 && cells[1].getContents() != null  ) //FAB VENDOR
                {
                    fabActivity = baseProduct.createActivity( baseProduct.getBaseProductName(), "FAB", "FAB" );
                    fabActivity.addVendor( cells[1].getContents().trim() );
                }
                /*else
                {
                    log( "**NOT PORTED**Shipping Location Missing for the row:" + (rowCount+1) );
                    continue;
                }*/
                if ( noOfCells > 2 && cells[2].getContents() != null ) //Prod Grp
                {
                    baseProduct.setProdGrp(cells[2].getContents().trim());
                }
                if ( noOfCells > 3 && cells[3].getContents() != null ) //PkG
                {
                    baseProduct.setPackageId( cells[3].getContents().trim() );
                }
                if ( noOfCells > 4 && cells[4].getContents() != null ) //Pkg Size
                {
                    baseProduct.setPackageSize(cells[4].getContents().trim());
                }
                if ( noOfCells > 5 && cells[5].getContents() != null && cells[5].getContents().trim().length() > 0 ) //Lead Ct
                {
                    baseProduct.setLeadCount(cells[5].getContents().trim());
                }                
                if ( noOfCells > 6 && cells[6].getContents() != null ) //Gross DPW
                {
                    fabActivity.setParameter( "Gross Die/Wafer", cells[6].getContents().trim());
                }
                if ( noOfCells > 7 && cells[7].getContents() != null ) //Plan NDW
                {
                    fabActivity.setParameter( "Plan NDW", cells[7].getContents().trim());
                }
                if ( noOfCells > 8 && cells[8].getContents() != null ) //Sort Y / N
                {
                    if ( "Y".equalsIgnoreCase( cells[8].getContents().trim() ) )
                    {
                        wsActivity = baseProduct.createActivity( baseProduct.getBaseProductName(), "Wafer Bank", "Wafer Store" );
                        baseProduct.createTransition( fabActivity, wsActivity );
                        sortActivity = baseProduct.createActivity( baseProduct.getBaseProductName(), "SORT", "SORT" );
                        sortActivity.setBinsRequired(true);
                        baseProduct.createTransition(  wsActivity, sortActivity );
                        dbActivity = baseProduct.createActivity( baseProduct.getBaseProductName(), "Die Bank", "Die Bank" );
                        baseProduct.createTransition( sortActivity, dbActivity );
                    }
                    else//NO WAFER STORE AND SORT PROCESS
                    {
                        dbActivity = baseProduct.createActivity( baseProduct.getBaseProductName(), "Die Bank", "Die Bank" );
                        baseProduct.createTransition( fabActivity, dbActivity );
                    }

                }
                if ( noOfCells > 9 && cells[9].getContents() != null ) //Tester Sort
                {
                    if ( sortActivity != null )
                    {
                        sortActivity.setParameter( "Sort Tester", cells[9].getContents().trim() );
                    }
                }
                if ( noOfCells > 10 && cells[10].getContents() != null ) //Tester FT
                {
                    baseProduct.setTesterFT( cells[10].getContents().trim() );
                }
                if ( noOfCells > 11 && cells[11].getContents() != null ) //Test UPD
                {
                    //Need clarification
                }
                if ( noOfCells > 12 && cells[12].getContents() != null ) //Sort Loc
                {
                    if ( sortActivity != null )
                    {
                        sortActivity.addVendor( cells[12].getContents().trim() );
                        wsActivity.setVendors( sortActivity.getVendors() );
                    }
                }
                if ( noOfCells > 13 && cells[13].getContents() != null ) //Assy 1
                {
                    baseProduct.setAssy1( cells[13].getContents().trim() );
                }
                if ( noOfCells > 14 && cells[14].getContents() != null ) //Assy 2
                {
                    baseProduct.setAssy2(cells[14].getContents().trim());
                }
                if ( noOfCells > 15 && cells[15].getContents() != null ) //Assy 3
                {
                    baseProduct.setAssy3(cells[15].getContents().trim());
                }
                if ( noOfCells > 16 && cells[16].getContents() != null ) //Test 1
                {                    
                    baseProduct.setTest1(cells[16].getContents().trim());
                }
                if ( noOfCells > 17 && cells[17].getContents() != null ) //Test 2
                {
                    baseProduct.setTest2(cells[17].getContents().trim());
                }
                if ( noOfCells > 18 && cells[18].getContents() != null ) //Test 3
                {
                    baseProduct.setTest3(cells[18].getContents().trim());
                }
                if ( noOfCells > 19 && cells[19].getContents() != null ) //FG 1
                {
                    baseProduct.setFg1(cells[19].getContents().trim());
                }
                if ( noOfCells > 20 && cells[20].getContents() != null ) //FG 2
                {
                    baseProduct.setFg2(cells[20].getContents().trim());
                }
                if ( noOfCells > 21 && cells[21].getContents() != null && cells[21].getContents().trim().length() > 0) //Equivalent partnumber
                {
                   fabActivity.setDupPartNumbers(cells[21].getContents().trim() );
                   if ( sortActivity != null )
                   {
                        wsActivity.setDupPartNumbers( cells[21].getContents().trim() );
                        sortActivity.setDupPartNumbers( cells[21].getContents().trim() );
                   }
                   dbActivity.setDupPartNumbers( cells[21].getContents().trim() );
                }
            }            
        }
        noOfRows  = assmPartsSheet.getRows();
        for ( int rowCount = 2; rowCount < noOfRows; rowCount++ )
        {
            cells = assmPartsSheet.getRow( rowCount );
            noOfCells = cells.length;
            BaseProduct baseProduct = null;
            Activity dbActivity = null;
            Activity assyActivity = null;
            Activity csActivity = null;
            Activity ftActivity = null;
            Activity eolActivity = null;
            Activity fgActivity = null;
            String fgProductName = null;
            boolean isPrimaryFGPN = false;
            String basePartNumber = null;
            if ( noOfCells > 0  )
            {
                if ( cells[0].getContents() != null && cells[0].getContents().trim().length() > 0 ) //Manufacturing Part
                {
                    fgProductName = cells[0].getContents().trim();
                }
                else
                {
                    log( "**NOT PORTED[assmPartsSheet]**FG Product Name Missing for the row:" + (rowCount+1) );
                    continue;
                }
                if ( noOfCells > 1 && cells[1].getContents() != null  ) //Primary MFG PN
                {
                     isPrimaryFGPN = "Primary".equalsIgnoreCase( cells[1].getContents().trim() );
                }
                if ( noOfCells > 2 && cells[2].getContents() != null  ) //Base PN
                {
                    basePartNumber = cells[2].getContents().trim();

                    baseProduct = (BaseProduct)baseProductMap.get( basePartNumber );
                    
                    if ( baseProduct == null )
                    {
                        log( "**NOT PORTED[assmPartsSheet]**Base Part Number "+basePartNumber+" is not found for the row:" + (rowCount+1) );
                        continue;
                    }
                    else
                    {
                        dbActivity = baseProduct.getActivity( "Die Bank" );
                        assyActivity = baseProduct.createActivity( fgProductName, "Assembly", "Assembly" );
                        csActivity = baseProduct.createActivity( fgProductName, "Pre Test", "Class Store" );
                        ftActivity = baseProduct.createActivity( fgProductName, "FT", "TEST" );
                        ftActivity.setBinsRequired(false);
                        eolActivity = baseProduct.createActivity( fgProductName, "EOL", "Class Store" );
                        fgActivity = baseProduct.createActivity( fgProductName, "FG", "Finished Goods" );
                        fgActivity.setPrimaryFGPN( isPrimaryFGPN );
                    }
                }
                else
                {
                    log( "**NOT PORTED[assmPartsSheet]**Base Part Number Missing for the row:" + (rowCount+1) );
                    continue;
                }
                if ( noOfCells > 3 && cells[3].getContents() != null ) //Marketing Part
                {
                    fgActivity.setMktPartNumber(cells[3].getContents().trim());
                }
                if ( noOfCells > 4 && cells[4].getContents() != null ) //Prod Grp
                {
                    //IGNORE
                }
                if ( noOfCells > 5 && cells[5].getContents() != null ) //Chipset 1
                {
                    fgActivity.setParameter("Chipset1",cells[5].getContents().trim());
                }
                if ( noOfCells > 6 && cells[6].getContents() != null ) //Chipset 2
                {
                    fgActivity.setParameter("Chipset2",cells[6].getContents().trim());
                }
                if ( noOfCells > 7 && cells[7].getContents() != null && cells[7].getContents().trim().length() > 0 ) //Prod Status
                {
                    assyActivity.setPartStatus( cells[7].getContents().trim() );
                    csActivity.setPartStatus( cells[7].getContents().trim() );
                    ftActivity.setPartStatus( cells[7].getContents().trim() );
                    eolActivity.setPartStatus( cells[7].getContents().trim() );
                    fgActivity.setPartStatus( cells[7].getContents().trim() );
                }
                if ( noOfCells > 8 && cells[8].getContents() != null ) //Chip Fam
                {
                    fgActivity.setParameter( "Chip Family", cells[8].getContents().trim());
                }
                if ( noOfCells > 9 && cells[9].getContents() != null ) //Band
                {
                    //IGNORE
                    //fgActivity.setParameter( "Band", cells[9].getContents().trim());
                }
                if ( noOfCells > 10 && cells[10].getContents() != null ) //Performance
                {
                    fgActivity.setParameter( "Performance", cells[10].getContents().trim());
                }
                if ( noOfCells > 11 && cells[11].getContents() != null ) //Port
                {
                    fgActivity.setParameter( "Port", cells[11].getContents().trim());
                }
                if ( noOfCells > 12 && cells[12].getContents() != null ) //PKG
                {
                    assyActivity.setParameter( "Package ID", cells[12].getContents().trim() );
                }
                if ( noOfCells > 13 && cells[13].getContents() != null ) //Pkg Size
                {
                    assyActivity.setParameter( "Package Size", cells[13].getContents().trim() );
                }
                if ( noOfCells > 14 && cells[14].getContents() != null ) //Lead Count
                {
                    assyActivity.setParameter( "Lead Count", cells[14].getContents().trim() );
                }
                if ( noOfCells > 15 && cells[15].getContents() != null ) //Tester
                {
                    ftActivity.setParameter( "FT Tester", cells[15].getContents() );
                }
                //16 ignore
                if ( noOfCells > 17 && cells[17].getContents() != null ) //Assy1
                {
                    assyActivity.addVendor( cells[17].getContents().trim() );
                }
                if ( noOfCells > 18 && cells[18].getContents() != null ) //Assy2
                {
                    assyActivity.addVendor( cells[18].getContents().trim() );
                }
                if ( noOfCells > 19 && cells[19].getContents() != null ) //Assy3
                {
                    assyActivity.addVendor( cells[19].getContents().trim() );
                }
                if ( noOfCells > 20 && cells[20].getContents() != null ) //Test1
                {
                    ftActivity.addVendor( cells[20].getContents().trim() );
                }
                if ( noOfCells > 21 && cells[21].getContents() != null ) //Test2
                {
                    ftActivity.addVendor( cells[21].getContents().trim() );
                }
                if ( noOfCells > 22 && cells[22].getContents() != null ) //Test3
                {
                    ftActivity.addVendor( cells[22].getContents().trim() );
                }
                if ( noOfCells > 23 && cells[23].getContents() != null ) //Fg1
                {
                    fgActivity.addVendor( cells[23].getContents().trim() );
                }
                if ( noOfCells > 24 && cells[24].getContents() != null ) //FG2
                {
                    fgActivity.addVendor( cells[24].getContents().trim() );
                }
                if ( noOfCells > 25 && cells[25].getContents() != null && cells[25].getContents().trim().length() > 0 ) //Prod Status
                {
                    assyActivity.setDupPartNumbers( cells[25].getContents().trim() );
                    csActivity.setDupPartNumbers( cells[25].getContents().trim() );
                    ftActivity.setDupPartNumbers( cells[25].getContents().trim() );
                    eolActivity.setDupPartNumbers( cells[25].getContents().trim() );
                    fgActivity.setDupPartNumbers( cells[25].getContents().trim() );
                }
                if ( basePartNumber != null )
                {
                    baseProduct = (BaseProduct)baseProductMap.get( basePartNumber );
                    if ( baseProduct == null )
                    {
                        log( "**NOT PORTED[assmPartsSheet]**Base Part Number "+basePartNumber+" is not found for the row:" + (rowCount+1) );
                        continue;
                    }
                    else
                    {
                        dbActivity.setVendors( assyActivity.getVendors() );
                        csActivity.setVendors( ftActivity.getVendors() );
                        eolActivity.setVendors( ftActivity.getVendors() );

                        baseProduct.createTransition( dbActivity, assyActivity );
                        baseProduct.createTransition( assyActivity, csActivity );
                        baseProduct.createTransition( csActivity, ftActivity );
                        baseProduct.createTransition( ftActivity, eolActivity );
                        baseProduct.createTransition( eolActivity, fgActivity );
                    }
                }
            }
        }
        return new ArrayList( baseProductMap.values() );
    }
    public static void main ( String[] args ) throws Exception
    {
        ProductParser productParser = new ProductParser();
        productParser.execute();
    }
    private String getXPDL( BaseProduct baseProduct )
    {
        StringBuffer xpdl = new StringBuffer();
        xpdl.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" );
        xpdl.append ( "<Package Id=\""+baseProduct.getBaseProductName()+"\" xmlns=\"http://www.wfmc.org/2002/XPDL1.0\" xmlns:xpdl=\"http://www.wfmc.org/2002/XPDL1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.wfmc.org/2002/XPDL1.0 http://wfmc.org/standards/docs/TC-1025_schema_10_xpdl.xsd\">");
        xpdl.append( "<Workflowprocesses>" );
        xpdl.append( "<workflowprocess Id=\""+baseProduct.getBaseProductName()+"_Work\">" );
        xpdl.append( "<Activities>" );
        //---
        for ( int i=0; i<baseProduct.getActivityList().size(); i++ )
        {
            Activity activity = (Activity)baseProduct.getActivityList().get(i);
            xpdl.append( "<Activity Id=\""+activity.getId()+"\" Type=\""+activity.getType()+"\" name=\""+activity.getName()+"\"><ExtendedAttributes>" );
            xpdl.append( "<ExtendedAttribute Name=\"bounds\" Value=\""+activity.getBounds()+"\"/>" );
            xpdl.append( "<ExtendedAttribute Name=\"processStepId\" Value=\"\"/>");
            xpdl.append( "<ExtendedAttribute Name=\"partnumber\" Value=\""+activity.getPartNumber()+"\"/>" );
            
            Map activityParams = activity.getParameters();
            String parameters = "";
            if( processParametersMap != null && processParametersMap.containsKey( activity.getName() ) && ( ( HashMap ) processParametersMap.get( activity.getName() ) ).containsKey( "parameters" )  )
			{
				Vector defaultParametersList = (Vector)( ( HashMap ) processParametersMap.get( activity.getName() ) ).get( "parameters" );
                for ( int j=0; j<defaultParametersList.size(); j++ )
                {
                   Vector parameter = (Vector)defaultParametersList.get(j);
                    if ( activityParams.containsKey( parameter.get(0) ) )
                    {
                        parameters += parameter.get(0) + "=" + parameter.get(1) + "=" + activityParams.get(parameter.get(0))+";";
                        activityParams.remove(parameter.get(0));
                    }
                    else
                    {
                        parameters += parameter.get(0) + "=" + parameter.get(1) + "=" + parameter.get(2)+";";
                    }
                }
            }
            Iterator keyItr = activityParams.keySet().iterator();            
            while( keyItr.hasNext() )
            {
                String paramName = (String)keyItr.next();
                String paramValue = (String)activityParams.get(paramName);
                parameters += paramName + "=" + "TEXT" + "=" + paramValue+";";
            }

            xpdl.append ( "<ExtendedAttribute Name=\"parameters\" Value=\""+parameters+"\"/>" );
            xpdl.append( "<ExtendedAttribute Name=\"dupPartNumbers\" Value=\""+activity.getDupPartNumbers()+"\"/>" );
            xpdl.append( "<ExtendedAttribute Name=\"comments\" Value=\"\"/>" );
            xpdl.append( "<ExtendedAttribute Name=\"vendors\">" );
            for ( int j=0; j < activity.getVendors().size(); j++ )
            {
                Vendor vendor = (Vendor)activity.getVendors().get(j);
                xpdl.append( "<Vendor>");
                xpdl.append( "<VendorAttribute Name=\"select\" Value=\"true\"/>");
                xpdl.append( "<VendorAttribute Name=\"priority\" Value=\"0\"/>" );
                xpdl.append( "<VendorAttribute Name=\"locationName\" Value=\""+vendor.getLocationName()+"\"/>" );
                xpdl.append( "<VendorAttribute Name=\"split\" Value=\"0\"/>" );
                xpdl.append( "<VendorAttribute Name=\"capacity/weeek\" Value=\"0\"/>" );
                xpdl.append( "<VendorAttribute Name=\"cycleTimeNormal\" Value=\"\"/>" );
                xpdl.append( "<VendorAttribute Name=\"cycleTimeExpress\" Value=\"\"/>" );
                xpdl.append( "</Vendor>" );
            }
            xpdl.append( "</ExtendedAttribute>" );
            xpdl.append( "<ExtendedAttribute Name=\"partStatus\" Value=\""+activity.getPartStatus()+"\"/>" );
            xpdl.append( "<ExtendedAttribute Name=\"productGroup\" Value=\""+baseProduct.getProdGrp()+"\"/>" );
            if ( "SORT".equalsIgnoreCase( activity.getType() ) || "TEST".equalsIgnoreCase( activity.getType() ) )
            {
                xpdl.append ( "<ExtendedAttribute Name=\"binsRequired\" Value=\""+activity.isBinsRequired()+"\"/>" );
                if ( activity.isBinsRequired() )
                {
                    xpdl.append( "<ExtendedAttribute Name=\"goodBinNumber\" Value=\""+activity.getGoodBinNumber()+"\"/>" );
                    xpdl.append( "<ExtendedAttribute Name=\"rejectedBinNumber\" Value=\""+activity.getRejectedBinNumber()+"\"/>" );
                }
            }
            else if ( "Finished Goods".equalsIgnoreCase( activity.getType() ) )
            {
                xpdl.append( "<ExtendedAttribute Name=\"mktPartNumber\" Value=\""+activity.getMktPartNumber()+"\"/>" );
                xpdl.append( "<ExtendedAttribute Name=\"isApprovedProduct\" Value=\"true\"/>" );
                xpdl.append( "<ExtendedAttribute Name=\"isPrimaryFGProduct\" Value=\""+activity.isPrimaryFGPN()+"\"/>" );
            }
            xpdl.append( "</ExtendedAttributes></Activity>" );
        }
        //---
        xpdl.append ( "</Activities>" );
        xpdl.append( "<Transitions>" );
        //--
        for ( int i=0; i < baseProduct.getTransitionList().size(); i++ )
        {
            Transition transition = (Transition)baseProduct.getTransitionList().get(i);
            xpdl.append( "<Transition From=\""+transition.getFrom()+"\" Id=\""+transition.getId()+"\" Name=\"\" To=\""+transition.getTo()+"\">" );
            xpdl.append( "<ExtendedAttributes>" );
            xpdl.append( "<ExtendedAttribute Name=\"bounds\" Value=\""+transition.getBounds()+"\"/>");
            xpdl.append( "<ExtendedAttribute Name=\"transitionStepId\" Value=\"\"/>" );
            xpdl.append( "<ExtendedAttribute Name=\"transportLocations\" Value=\"\"/>" );
            xpdl.append( "</ExtendedAttributes>" );
            xpdl.append( "</Transition>" );
        }
        //---
        xpdl.append ( "</Transitions>" );
        xpdl.append( "</workflowprocess></Workflowprocesses></Package>" );
        return xpdl.toString();
    }
}
